package util.jackson.serializer;

import com.fasterxml.jackson.databind.module.SimpleModule;
import shared.model.ValueObject;

import java.util.ServiceLoader;

/**
 * @author Gregory Boissinot
 */
public class DiscoverableSubtypeValueObjectModule extends SimpleModule {

    public DiscoverableSubtypeValueObjectModule() {
        ServiceLoader<ValueObject> serviceLoader = ServiceLoader.load(ValueObject.class);
        serviceLoader.reload();
        for (ValueObject valueObject : serviceLoader) {
            final Class<? extends ValueObject> aClass = valueObject.getClass();
            final Class<?>[] interfaces = getTopLevelInterfaceClass(aClass);
            if (interfaces != null) {
                for (Class<?> anInterfaceClass : interfaces) {
                    addAbstractTypeMapping((Class<Object>) anInterfaceClass, valueObject.getClass());
                }
            }
        }
    }

    private Class<?>[] getTopLevelInterfaceClass(Class<? extends ValueObject> aClass) {
        final Class<?>[] interfaces = aClass.getInterfaces();

        if (interfaces.length == 0) {
            throw new IllegalStateException();
        }

        for (Class<?> anInterface : interfaces) {
            final Class<?>[] interfaces1 = anInterface.getInterfaces();
            if (interfaces1.length != 0) {
                return interfaces1;
            }
        }

        return interfaces;
    }
}
